import puppeteer from 'puppeteer-core'
import { Page } from 'puppeteer-core'
import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

type NoteRes = {
  code: number
  success: boolean
  msg: string
  data: {
    has_more: boolean
    items: {
      id: string
      model_type: string
      note_card: {
        type: string
        display_title: string
      }
      xsec_token: string
    }[]
  }
}

const results: {
  [keyword: string]: {
    id: string
    display_title: string
    url: string // 分享链接
  }[]
} = {}

async function launchBrowser() {
  const browser = await puppeteer.launch({
    // 使用已安装的 Chrome
    executablePath: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
    headless: false, // 显示浏览器界面
    defaultViewport: null,
    userDataDir: path.resolve(__dirname, 'browser-data'), // 保存用户数据目录
  })

  const page = await browser.newPage()
  return { browser, page }
}

// 设置请求拦截器
async function setupResponseListener(page: Page) {
  await page.setRequestInterception(true)

  // 放行所有请求
  page.on('request', (request) => {
    request.continue()
  })

  // 监听响应
  page.on('response', async (response) => {
    const url = response.url()
    if (url.includes('api/sns/web/v1/search/notes')) {
      try {
        const postData = response.request().postData()
        // 只监听"最新"的响应
        if (postData?.includes('time_descending')) {
          const data = (await response.json()) as NoteRes
          const { keyword } = JSON.parse(postData)
          // url举例：'https://www.xiaohongshu.com/discovery/item/6768ccd3000000001301a91b?source=webshare&xhsshare=pc_web&xsec_token=AB86_5lWwxZ6fF3p1lG8cdAmgw9UEGtYo7rdzwsM-9dOw=&xsec_source=pc_share'

          // 处理搜索结果数据
          data.data.items.forEach((item) => {
            const note = {
              id: item.id,
              display_title: item?.note_card?.display_title || '',
              url: `https://www.xiaohongshu.com/discovery/item/${item.id}?source=webshare&xsec_token=${item.xsec_token}`,
            }
            if (!results[keyword]) {
              results[keyword] = []
            } else {
              console.log('正在爬取', keyword, '第', results[keyword].length + 1, '条')
              results[keyword].push(note)
            }
          })
        }
      } catch (e) {
        console.error('解析响应数据失败:', e)
      }
    }
  })
}

async function main() {
  const { browser, page } = await launchBrowser()
  const keywords = ['运营', '店长', '老板', '跨境', '行政', '人事']

  try {
    await setupResponseListener(page)

    for (const keyword of keywords) {
      await page.goto(`https://www.xiaohongshu.com/search_result?keyword=${encodeURIComponent(keyword)}`)
      // 如果页面上有登陆弹窗，等待扫码登陆
      try {
        // 尝试检测登录框
        const loginContainer = await page.waitForSelector('.login-container', { visible: true, timeout: 3000 })
        if (loginContainer) {
          console.log('等待人工扫码登录...请在1分钟内扫码')
          await page.waitForSelector('.login-container', { hidden: true, timeout: 600000 })
          console.log('扫码登录成功')
          await page.waitForNavigation({ waitUntil: 'networkidle0' })
        }
      } catch (error) {
        // 如果没有检测到登录框，说明已经登录，继续执行
        console.log('未检测到登录框，继续执行...')
      }

      // hover 到 class=filter 上，然后点击 dropdown-items 里的"最新"选项
      await page.waitForSelector('.filter')
      await page.hover('.filter')

      // 点击"最新"选项
      const spans = await page.$$('.dropdown-items li span')
      for (const span of spans) {
        const text = await span.evaluate((el) => el.textContent)
        if (text?.includes('最新')) {
          await span.click()
          break
        }
      }

      // 滚动页面并等待响应
      while ((results[keyword]?.length || 0) < 50) {
        await new Promise((resolve) => setTimeout(resolve, 3000))
        console.log('当前关键词', keyword, '结果数', results[keyword]?.length)
        console.log('执行滚动...')
        await page.evaluate(() => {
          const scrollHeight = document.documentElement.scrollHeight
          window.scrollTo({
            top: scrollHeight,
            behavior: 'smooth',
          })
        })
      }
    }
  } catch (error) {
    console.error('发生错误:', error)
  } finally {
    // 将结果保存到json文件
    console.log('########## 结束保存到 xhs.json ##########')
    const resPath = path.resolve(__dirname, 'xhs.json')
    fs.writeFileSync(resPath, JSON.stringify(results, null, 2))

    await browser.close()
  }
}

main()
